﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using com.pro2e.console.service.auth.vo;
using Iesi.Collections.Generic;
using com.pro2e.console.core.hibernate;
using com.pro2e.console.core.util;
using com.pro2e.console.service.auth;
using NHibernate.Proxy;
using NHibernate;

/// <summary>
/// UserMenuFuncContainer 使用 Singleton pattern
/// </summary>
/// 
namespace com.pro2e.console.service.auth.vo
{
    public class UserMenuFuncContainer
    {
        log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private static UserMenuFuncContainer userMenuFunc = null;

        /// <summary>
        /// 登入者的快取
        /// </summary>
        private Dictionary<string, LoginUser> UserDic = new Dictionary<string, LoginUser>();

        /// <summary>
        /// 路徑與功能
        /// </summary>
        public Dictionary<string, List<int>> PathFunc = new Dictionary<string, List<int>>();
        public Dictionary<int, LoginRole> RoleDic = new Dictionary<int, LoginRole>();
        public IList<MenuFunc> AllMenu = null;

        private UserMenuFuncContainer()
        {

        }

        public static UserMenuFuncContainer GetInstance()
        {
            log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            log.Info("....System Init....");

            lock (typeof(UserMenuFuncContainer))
            {
                if (userMenuFunc == null)
                {
                    UserMenuFuncContainer container = new UserMenuFuncContainer();
                    userMenuFunc = container;

                    //載入快取全部的menu
                    container.AllMenu = new List<MenuFunc>();

                    initAllMenu();
                    //載入全部的Role的功能
                    initAllRole();

                    initPathFunc();
                }
                return userMenuFunc;
            }
        }

        private static void initPathFunc()
        {
            IList<MenuFunc> menuList = userMenuFunc.AllMenu;
            Dictionary<string, List<int>> myPathFunc = userMenuFunc.PathFunc;
            //top menu
            foreach (MenuFunc menuFunc in menuList) 
            {
                if (menuFunc.SubFuncs != null && menuFunc.SubFuncs.Count > 0) 
                {
                    foreach (MenuFunc subMenuFunc in menuFunc.SubFuncs) 
                    {
                        string path  = subMenuFunc.MainPath;
                        if (!string.IsNullOrEmpty(path))
                        {
                            if (!myPathFunc.ContainsKey(path))
                            {
                                List<int> funList = new List<int>();
                                funList.Add(subMenuFunc.Id);
                                myPathFunc.Add(path, funList);
                            }
                            else 
                            {
                                List<int> funList = myPathFunc[path];
                                funList.Add(subMenuFunc.Id);
                            }
                        }     
                    }
                }
                
               
            }
        }

        private static void initAllRole()
        {

            AuthService authService = new AuthService();

            IList<LoginRole> roleList = authService.DaoGetAllVO<LoginRole>();
            userMenuFunc.RoleDic = new Dictionary<int, LoginRole>();

            foreach (LoginRole role in roleList)
            {
                NHibernateUtil.Initialize(role.MenuFuncs);
                userMenuFunc.RoleDic.Add(role.RoleId, role);
            }
        }

        public void ReloadAllMenu()
        {
            initAllMenu();
            initAllRole();
        }

        private static void initAllMenu()
        {

            AuthService authService = new AuthService();

            IList<MenuFunc> iList = authService.GetTopMenuFunc();

            if (iList != null && iList.Count > 0)
            {
                foreach (MenuFunc menu in iList)
                {
                    if (menu.SubFuncs != null && menu.SubFuncs.Count > 0)
                    {
                        foreach (MenuFunc subFunc in menu.SubFuncs)
                        {
                            NHibernateUtil.Initialize(subFunc.FuncionPaths);
                        }
                    }
                }
            }
            userMenuFunc.AllMenu = iList;
        }

        /// <summary>
        /// 重新建立Container
        /// </summary>
        public void ResetAll()
        {
            userMenuFunc = null;
            RoleDic = null;
        }


        /// <summary>
        /// 重新載入使用者(當更換權限時要reload)
        /// </summary>
        /// <param name="userId"></param>
        public void Reload(string userId)
        {
            userMenuFunc.UserDic.Remove(userId);
            loadUser(userId);
        }

        public LoginUser GetUser(string userId)
        {
            UserDic = userMenuFunc.UserDic;

            initData(userId);

            return UserDic[userId];
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="userId"></param>
        private void initData(string userId)
        {
            UserDic = userMenuFunc.UserDic;

            if (UserDic.Count > 0)
            {
                bool isMatched = false;
                foreach (string inUserId in UserDic.Keys)
                {
                    if (inUserId.Equals(userId))
                    {
                        isMatched = true;
                        break;
                    }
                }

                if (isMatched == false)
                {
                    loadUser(userId);
                }
            }
            else
            {
                loadUser(userId);
            }
        }


        /// <summary>
        /// 載入user的資料
        /// </summary>
        /// <param name="userId"></param>
        private void loadUser(string userId)
        {
            UserDic = userMenuFunc.UserDic;

            AuthService authService = new AuthService();
            LoginUser user = authService.LoadLoginUser(userId);

            //動態載入開始
            //

            //==================動態載入開始
            if (user.BelongRoles != null && user.BelongRoles.Count > 0)
            {
                foreach (LoginRole role in user.BelongRoles)
                {
                    if (role.MenuFuncs != null && role.MenuFuncs.Count > 0)
                    {
                        foreach (MenuFunc menufunc in role.MenuFuncs)
                        {
                            NHibernateUtil.Initialize(menufunc.FuncionPaths);
                        }
                    }
                }

                /*
                int count = user.BelongRoles.Count;
                if (user.BelongRoles[0].MenuFuncs != null)
                {
                    count = user.BelongRoles[0].MenuFuncs.Count;
                    if (user.BelongRoles[0].MenuFuncs[0].FuncionPaths != null)
                    {
                        count = user.BelongRoles[0].MenuFuncs[0].FuncionPaths.Count;
                        if (count>0) 
                        {
                            int id = user.BelongRoles[0].MenuFuncs[0].FuncionPaths[0].Id;
                        }
                    }
                }
                 */
            }

            //==================動態載入結束
            log.Debug("lock UserMenuFuncContainer loadUser");
            lock (typeof(UserMenuFuncContainer))
            {
                UserDic.Remove(userId);
                UserDic.Add(userId, user);
            }
        }

    }
}